package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"os/user"
	"strings"
	"time"
)

var (
	currentUser, _ = user.Current()
	pwd, _         = os.Getwd()
	includes       = []string{"install bspwm Catpuccin", "install i3 Catpuccin", "install i3 Nordic", "install Software", "install Pictures"}
	arr            = [][]string{{"/.config/bspwm", "/.config/cava", "/.config/picom", "/.config/polybar", "/.config/rofi",
		"/.config/sxhkd", "/.icons"}, {"/.config/picom", "/.config/conky", "/.config/i3", "/.config/polybar",
		"/.config/rofi", "/.icons", "/.themes", "/.fonts"}, {"/.config/conky", "/.config/i3", "/.config/polybar",
		"/.config/rofi", "/.icons", "/.themes", "/.fonts"}, {"/.config/alacritty", "/.config/BetterDiscord",
		"/.config/btop", "/.config/fish", "/.config/kitty", "/.config/micro", "/.config/mpv", "/.config/neofetch",
		"/.config/ranger", "/.config/Thunar"}, {"/bspwm/Catpuccin", "/i3/Catpuccin", "/i3/Nordic", "/Software"}}
)

func main() {
	banner()
	choose := fzf(includes)
	switch choose {
	case 0, 1, 2, 3:
		for _, i := range arr[choose] {
			fmt.Println(pwd+arr[4][choose]+i, currentUser.HomeDir+i)
		}

	case 4:
		exist(pwd+"/Pictures", currentUser.HomeDir+"/Pictures")
	default:
		log.Fatal("Unknown number")
	}
	fmt.Println("Successfully installed")
}

func moveFile(path1, path2 string) error {
	err := os.Rename(path1, path2)
	if err != nil {
		log.Fatal(err)
	}
	return nil
}

func exist(path1, path2 string) {
	if _, err := os.Stat(path2); !os.IsNotExist(err) {
		moveFile(path2, path2+"-old")
	}
	moveFile(path1, path2)
}

func banner() {
	fmt.Println("    ____        __  _______ __ ")
	fmt.Println("   / __ \\____  / /_/ ____(_) /__  _____")
	fmt.Println("  / / / / __ \\/ __/ /_  / / / _ \\/ ___/")
	fmt.Println(" / /_/ / /_/ / /_/ __/ / / /  __(__  ) ")
	fmt.Println("/_____/\\____/\\__/_/   /_/_/\\___/____/  ")
	fmt.Println("\t\t\t\tby Allowri")
	time.Sleep(1 * time.Second)
}

func withFilter(command string, input func(in io.WriteCloser)) []string {
	shell := os.Getenv("SHELL")
	if len(shell) == 0 {
		shell = "sh"
	}
	cmd := exec.Command(shell, "-c", command)
	cmd.Stderr = os.Stderr
	in, _ := cmd.StdinPipe()
	go func() {
		input(in)
		in.Close()
	}()
	result, _ := cmd.Output()
	return strings.Split(string(result), "\n")
}

func fzf[T any](s []T) int {
	filtered := withFilter("fzf -m", func(in io.WriteCloser) {
		for key, value := range s {
			fmt.Fprintln(in, key, value)
			time.Sleep(5 * time.Millisecond)
		}
	})
	var num int
	if _, err := fmt.Sscanf(string(filtered[0]), "%d ", &num); err != nil {
		panic(err)
	}

	return num
}
